package com.zenithmind.library.pojo.domain;

import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zenithmind.common.base.BaseEntity;
import com.zenithmind.library.enums.ReservationStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 预约记录实体
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "预约记录实体", description = "图书预约记录信息")
@TableName("lib_reservation")
public class Reservation extends BaseEntity {

    @NotNull(message = "用户ID不能为空")
    @Schema(description = "预约用户ID")
    private String userId;

    @NotNull(message = "图书ID不能为空")
    @Schema(description = "图书ID")
    private String bookId;

    @Schema(description = "图书副本ID")
    private String bookCopyId;

    @Schema(description = "预约日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate reservationDate;

    @Schema(description = "预约到期日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate expirationDate;

    @Schema(description = "可取书日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate availableDate;

    @Schema(description = "取书日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate pickupDate;

    @Schema(description = "预约状态")
    private Integer status;

    @Schema(description = "排队位置")
    private Integer queuePosition;

    @Schema(description = "预约优先级")
    private Integer priority;

    @Schema(description = "通知方式 (1-邮件, 2-短信, 3-站内信)")
    private Integer notificationMethod;

    @Schema(description = "是否已通知 (0-否, 1-是)")
    private Integer notified;

    @Schema(description = "通知时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime notificationTime;

    @Schema(description = "取消原因")
    @Size(max = 500, message = "取消原因长度不能超过500个字符")
    private String cancellationReason;

    @Schema(description = "取消时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime cancellationTime;

    @Schema(description = "操作员ID")
    private String operatorId;

    @Schema(description = "备注")
    @Size(max = 500, message = "备注长度不能超过500个字符")
    private String remarks;

    /**
     * 获取预约状态枚举
     */
    public ReservationStatus getReservationStatus() {
        return ReservationStatus.getByCode(this.status);
    }

    /**
     * 设置预约状态枚举
     */
    public void setReservationStatus(ReservationStatus reservationStatus) {
        this.status = reservationStatus != null ? reservationStatus.getCode() : null;
    }

    /**
     * 判断是否已过期
     */
    public boolean isExpired() {
        return expirationDate != null && LocalDate.now().isAfter(expirationDate);
    }

    /**
     * 判断是否可取书
     */
    public boolean isAvailableForPickup() {
        ReservationStatus reservationStatus = getReservationStatus();
        return reservationStatus == ReservationStatus.AVAILABLE && 
               availableDate != null && 
               !LocalDate.now().isBefore(availableDate) &&
               !isExpired();
    }

    /**
     * 判断是否为活跃预约
     */
    public boolean isActive() {
        ReservationStatus reservationStatus = getReservationStatus();
        return reservationStatus != null && reservationStatus.isActive() && !isExpired();
    }
}
